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/helper.h>
8#include <molpro/linalg/itsolv/subspace/Dimensions.h>
9#include <molpro/linalg/itsolv/wrap.h>
10#include <molpro/linalg/itsolv/Logger.h>
11
12#include <molpro/linalg/array/DistrArray.h>
13#include <molpro/linalg/array/util/Distribution.h>
14
15#include <memory>
16#include <ostream>
17#include <vector>
18
19namespace molpro::profiler {
20class Profiler;
21}
22namespace molpro::linalg::itsolv {
23
24template <typename T>
26 template <typename C>
27 constexpr static std::true_type test(typename C::iterator*);
28
29 template <typename>
30 constexpr static std::false_type test(...);
31
32 constexpr static bool value =
33 std::is_same<std::true_type, decltype(test<typename std::remove_reference<T>::type>(0))>::value;
34};
35
36template <typename T, typename S,
37 typename = std::enable_if_t<std::is_base_of<molpro::linalg::array::DistrArray, T>::value>>
38void precondition_default(const VecRef<T>& action, const std::vector<S>& shift, const T& diagonals) {
39 // regularisation of the denominator, calibrated for double precision and rescaled to the working precision
40 const auto regulariser = precision_scaled<S>(1e-15);
41 auto diagonals_local_buffer = diagonals.local_buffer();
42 for (size_t k = 0; k < action.size(); k++) {
43 auto action_local_buffer = action[k].get().local_buffer();
44 auto& distribution = action[k].get().distribution();
45 auto range = distribution.range(molpro::mpi::rank_global());
46 for (auto i = range.first; i < range.second; i++)
47 (*action_local_buffer)[i - range.first] /= ((*diagonals_local_buffer)[i - range.first] - shift[k] + regulariser);
48 }
49}
50
51template <class T, typename S>
52void precondition_default(const VecRef<T>& action, const std::vector<S>& shift, const T& diagonals,
53 typename T::iterator* = nullptr // SFINAE
54) {
55 const auto regulariser = precision_scaled<S>(1e-15);
56 for (size_t k = 0; k < action.size(); k++) {
57 auto& a = action[k].get();
58 std::transform(diagonals.begin(), diagonals.end(), a.begin(), a.begin(),
59 [shift, k, regulariser](const auto& first, const auto& second) {
60 return second / (first - shift[k] + regulariser);
61 });
62 }
63}
64
65template <typename T, typename S,
66 typename = std::enable_if_t<!std::is_base_of<molpro::linalg::array::DistrArray, T>::value>, class = void>
67void precondition_default(const VecRef<T>& action, const std::vector<S>& shift, const T& diagonals,
68 typename std::enable_if<!has_iterator<T>::value, void*>::type = nullptr // SFINAE
69) {
70 throw std::logic_error("Unimplemented preconditioner");
71}
72
84template <typename R, typename P = std::map<size_t, typename R::value_type>>
85class Problem {
86public:
87 Problem() = default;
88 virtual ~Problem() = default;
89 using container_t = R;
90 using p_container_t = P;
91 using value_t = typename R::value_type;
92
101 virtual value_t residual(const R& parameters, R& residual) const { return 0; }
102
109 virtual void action(const CVecRef<R>& parameters, const VecRef<R>& action) const { return; }
110
121 virtual bool diagonals(container_t& d) const { return false; }
122
132 virtual void precondition(const VecRef<R>& residual, const std::vector<value_t>& shift) const { return; }
133
144 virtual void precondition(const VecRef<R>& residual, const std::vector<value_t>& shift, const R& diagonals) const {
146 }
147
155 virtual bool RHS(R& RHS, unsigned int instance) const { return false;}
156
162 virtual std::vector<value_t> pp_action_matrix(const std::vector<P>& pparams) const {
163 if (not pparams.empty())
164 throw std::logic_error("P-space unavailable: unimplemented pp_action_matrix() in Problem class");
165 return std::vector<value_t>(0);
166 }
167
174 virtual void p_action(const std::vector<std::vector<value_t>>& p_coefficients, const CVecRef<P>& pparams,
175 const VecRef<container_t>& actions) const {
176 if (not pparams.empty())
177 throw std::logic_error("P-space unavailable: unimplemented p_action() in Problem class");
178 }
179
189 virtual bool test_parameters(unsigned int instance, R& parameters) const { return false; }
190};
191
208template <class R, class Q, class P>
210public:
211 using value_type = typename R::value_type;
215 using VectorP = std::vector<value_type>;
220 using fapply_on_p_type = std::function<void(const std::vector<VectorP>&, const CVecRef<P>&, const VecRef<R>&)>;
221
222 virtual ~IterativeSolver() = default;
223 IterativeSolver() = default;
227 IterativeSolver<R, Q, P>& operator=(IterativeSolver<R, Q, P>&&) noexcept = default;
228
256 virtual bool solve(const VecRef<R>& parameters, const VecRef<R>& actions, const Problem<R>& problem,
257 bool generate_initial_guess = false) = 0;
258 virtual bool solve(R& parameters, R& actions, const Problem<R>& problem, bool generate_initial_guess = false) = 0;
259 virtual bool solve(std::vector<R>& parameters, std::vector<R>& actions, const Problem<R>& problem,
260 bool generate_initial_guess = false) = 0;
261
272 virtual int add_vector(const VecRef<R>& parameters, const VecRef<R>& actions) = 0;
273
274 // FIXME this should be removed in favour of VecRef interface
275 virtual int add_vector(std::vector<R>& parameters, std::vector<R>& action) = 0;
276 virtual int add_vector(R& parameters, R& action, value_type value = 0) = 0;
277
292 virtual size_t add_p(const CVecRef<P>& pparams, const array::Span<value_type>& pp_action_matrix,
293 const VecRef<R>& parameters, const VecRef<R>& action, fapply_on_p_type apply_p) = 0;
294
295 // FIXME Is this needed?
296 virtual void clearP() = 0;
297
299 virtual void solution(const std::vector<int>& roots, const VecRef<R>& parameters, const VecRef<R>& residual) = 0;
300
302 virtual void solution_params(const std::vector<int>& roots, const VecRef<R>& parameters) = 0;
303
305 virtual size_t end_iteration(const VecRef<R>& parameters, const VecRef<R>& residual) = 0;
306
311 virtual void finalize() = 0;
312
316 virtual bool end_iteration_needed() = 0;
317
328 virtual std::vector<size_t> suggest_p(const CVecRef<R>& solution, const CVecRef<R>& residual, size_t max_number,
329 value_type_abs threshold) = 0;
330
331 virtual void solution(const std::vector<int>& roots, std::vector<R>& parameters, std::vector<R>& residual) = 0;
332 virtual void solution(R& parameters, R& residual) = 0;
333 virtual void solution_params(const std::vector<int>& roots, std::vector<R>& parameters) = 0;
334 virtual void solution_params(R& parameters) = 0;
335 virtual size_t end_iteration(std::vector<R>& parameters, std::vector<R>& action) = 0;
336 virtual size_t end_iteration(R& parameters, R& action) = 0;
337
341 virtual const std::vector<int>& working_set() const = 0;
344 virtual std::vector<scalar_type> working_set_eigenvalues() const {
345 return std::vector<scalar_type>(working_set().size(), 0);
346 }
349 virtual size_t n_roots() const = 0;
350 virtual void set_n_roots(size_t nroots) = 0;
351 virtual const std::vector<scalar_type>& errors() const = 0;
352 virtual const Statistics& statistics() const = 0;
354 virtual void report(std::ostream& cout, bool endl = true) const = 0;
356 virtual void report() const = 0;
357
366 [[deprecated("Set the verbosity on the logger directly")]]
367 virtual void set_verbosity(Verbosity v) = 0;
368 virtual void set_verbosity(int v) = 0;
369 [[deprecated("Query the logger directly")]]
370 virtual Verbosity get_verbosity() const = 0;
371 virtual void set_max_iter(int n) = 0;
372 virtual int get_max_iter() const = 0;
373 virtual void set_max_p(int n) = 0;
374 virtual int get_max_p() const = 0;
375 virtual void set_p_threshold(value_type_abs thresh) = 0;
376 virtual value_type_abs get_p_threshold() const = 0;
377 virtual const subspace::Dimensions& dimensions() const = 0;
378 // FIXME Missing parameters: SVD threshold
381 virtual void set_options(const Options& options) = 0;
384 virtual std::shared_ptr<Options> get_options() const = 0;
389 virtual scalar_type value() const = 0;
394 virtual bool nonlinear() const = 0;
400 virtual const std::shared_ptr<molpro::profiler::Profiler>& profiler() const = 0;
405 virtual void set_logger(std::shared_ptr<Logger> logger) = 0;
406 virtual Logger &logger() = 0;
416 virtual bool test_problem(const Problem<R>& problem, R& v0, R& v1, int verbosity = 0,
417 value_type_abs threshold = 1e-5) const = 0;
418};
419
424template <class R, class Q, class P>
425class LinearEigensystem : public IterativeSolver<R, Q, P> {
426public:
429 virtual std::vector<scalar_type> eigenvalues() const = 0;
431 virtual void set_hermiticity(bool hermitian) = 0;
433 virtual bool get_hermiticity() const = 0;
434};
435
436template <class R, class Q, class P>
437class LinearEquations : public IterativeSolver<R, Q, P> {
438public:
440 virtual void add_equations(const CVecRef<R>& rhs) = 0;
441 virtual void add_equations(const std::vector<R>& rhs) = 0;
442 virtual void add_equations(const R& rhs) = 0;
443 virtual CVecRef<Q> rhs() const = 0;
445 virtual void set_hermiticity(bool hermitian) = 0;
447 virtual bool get_hermiticity() const = 0;
448};
449
451template <class R, class Q, class P>
452class Optimize : public IterativeSolver<R, Q, P> {};
453
455template <class R, class Q, class P>
456class NonLinearEquations : public IterativeSolver<R, Q, P> {};
457
458} // namespace molpro::linalg::itsolv
459
460#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:209
typename R::value_type value_type
The underlying type of elements of vectors.
Definition: IterativeSolver.h:211
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:214
virtual scalar_type value() const =0
Report the function value for the current optimum solution.
virtual void set_verbosity(Verbosity v)=0
virtual void set_convergence_threshold_value(value_type_abs thresh)=0
Sets the value convergence threshold.
virtual void report(std::ostream &cout, bool endl=true) const =0
Writes a report to cout output stream.
virtual std::vector< size_t > suggest_p(const CVecRef< R > &solution, const CVecRef< R > &residual, size_t max_number, value_type_abs threshold)=0
Get the solver's suggestion of which degrees of freedom would be best to add to the P-space.
IterativeSolver(IterativeSolver< R, Q, P > &&) noexcept=default
typename array::ArrayHandler< R, Q >::value_type scalar_type
Definition: IterativeSolver.h:213
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.
virtual void set_convergence_threshold(value_type_abs thresh)=0
Sets the convergence threshold.
virtual bool test_problem(const Problem< R > &problem, R &v0, R &v1, int verbosity=0, value_type_abs threshold=1e-5) const =0
Test a supplied problem class.
std::function< void(const std::vector< VectorP > &, const CVecRef< P > &, const VecRef< R > &)> fapply_on_p_type
Definition: IterativeSolver.h:220
virtual bool nonlinear() const =0
Report whether the class is a non-linear solver.
virtual void set_p_threshold(value_type_abs thresh)=0
virtual value_type_abs convergence_threshold() const =0
Reports the convergence threshold.
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 value_type_abs get_p_threshold() const =0
virtual void set_options(const Options &options)=0
std::vector< value_type > VectorP
Definition: IterativeSolver.h:217
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 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:344
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 value_type_abs convergence_threshold_value() const =0
Reports the value convergence threshold.
virtual const Statistics & statistics() const =0
virtual const std::vector< scalar_type > & errors() const =0
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:425
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:437
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:442
Solves non-linear system of equations using methods such as DIIS.
Definition: IterativeSolver.h:456
Optimises to a stationary point using methods such as L-BFGS.
Definition: IterativeSolver.h:452
Abstract class defining the problem-specific interface for the simplified solver interface to Iterati...
Definition: IterativeSolver.h:85
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:109
R container_t
Definition: IterativeSolver.h:89
P p_container_t
Definition: IterativeSolver.h:90
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:132
typename R::value_type value_t
Definition: IterativeSolver.h:91
virtual bool diagonals(container_t &d) const
Optionally provide the diagonal elements of the underlying kernel. If implemented and returning true,...
Definition: IterativeSolver.h:121
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:174
virtual std::vector< value_t > pp_action_matrix(const std::vector< P > &pparams) const
Calculate the kernel matrix in the P space.
Definition: IterativeSolver.h:162
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:101
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:189
virtual bool RHS(R &RHS, unsigned int instance) const
Return the inhomogeneous part of a linear equation system.
Definition: IterativeSolver.h:155
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:144
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition: helper.h:14
void precondition_default(const VecRef< T > &action, const std::vector< S > &shift, const T &diagonals)
Definition: IterativeSolver.h:38
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: linalg_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:25
static constexpr bool value
Definition: IterativeSolver.h:32
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