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
10#include <molpro/linalg/array/DistrArray.h>
11#include <molpro/linalg/array/util/Distribution.h>
12
13#include <memory>
14#include <ostream>
15#include <vector>
16
17namespace molpro::profiler {
18class Profiler;
19}
20namespace molpro::linalg::itsolv {
21
22template <typename T>
24 template <typename C>
25 constexpr static std::true_type test(typename C::iterator*);
26
27 template <typename>
28 constexpr static std::false_type test(...);
29
30 constexpr static bool value =
31 std::is_same<std::true_type, decltype(test<typename std::remove_reference<T>::type>(0))>::value;
32};
33
34template <typename T, typename = std::enable_if_t<std::is_base_of<molpro::linalg::array::DistrArray, T>::value>>
35void precondition_default(const VecRef<T>& action, const std::vector<double>& shift, const T& diagonals) {
36 auto diagonals_local_buffer = diagonals.local_buffer();
37 for (size_t k = 0; k < action.size(); k++) {
38 auto action_local_buffer = action[k].get().local_buffer();
39 auto& distribution = action[k].get().distribution();
40 auto range = distribution.range(molpro::mpi::rank_global());
41 for (auto i = range.first; i < range.second; i++)
42 (*action_local_buffer)[i - range.first] /= ((*diagonals_local_buffer)[i - range.first] - shift[k] + 1e-15);
43 }
44}
45
46template <class T>
47void precondition_default(const VecRef<T>& action, const std::vector<double>& shift, const T& diagonals,
48 typename T::iterator* = nullptr // SFINAE
49) {
50 for (size_t k = 0; k < action.size(); k++) {
51 auto& a = action[k].get();
52 std::transform(diagonals.begin(), diagonals.end(), a.begin(), a.begin(),
53 [shift, k](const auto& first, const auto& second) { return second / (first - shift[k] + 1e-15); });
54 }
55}
56
57template <typename T, typename = std::enable_if_t<!std::is_base_of<molpro::linalg::array::DistrArray, T>::value>,
58 class = void>
59void precondition_default(const VecRef<T>& action, const std::vector<double>& shift, const T& diagonals,
60 typename std::enable_if<!has_iterator<T>::value, void*>::type = nullptr // SFINAE
61) {
62 throw std::logic_error("Unimplemented preconditioner");
63}
64
76template <typename R, typename P = std::map<size_t, typename R::value_type>>
77class Problem {
78public:
79 Problem() = default;
80 virtual ~Problem() = default;
81 using container_t = R;
82 using value_t = typename R::value_type;
83
92 virtual value_t residual(const R& parameters, R& residual) const { return 0; }
93
100 virtual void action(const CVecRef<R>& parameters, const VecRef<R>& action) const { return; }
101
112 virtual bool diagonals(container_t& d) const { return false; }
113
123 virtual void precondition(const VecRef<R>& residual, const std::vector<value_t>& shift) const { return; }
124
135 virtual void precondition(const VecRef<R>& residual, const std::vector<value_t>& shift, const R& diagonals) const {
137 }
138
146 virtual bool RHS(R& RHS, unsigned int instance) const { return false;}
147
153 virtual std::vector<double> pp_action_matrix(const std::vector<P>& pparams) const {
154 if (not pparams.empty())
155 throw std::logic_error("P-space unavailable: unimplemented pp_action_matrix() in Problem class");
156 return std::vector<double>(0);
157 }
158
165 virtual void p_action(const std::vector<std::vector<value_t>>& p_coefficients, const CVecRef<P>& pparams,
166 const VecRef<container_t>& actions) const {
167 if (not pparams.empty())
168 throw std::logic_error("P-space unavailable: unimplemented p_action() in Problem class");
169 }
170
180 virtual bool test_parameters(unsigned int instance, R& parameters) const { return false; }
181};
182
199template <class R, class Q, class P>
201public:
202 using value_type = typename R::value_type;
206 using VectorP = std::vector<value_type>;
211 using fapply_on_p_type = std::function<void(const std::vector<VectorP>&, const CVecRef<P>&, const VecRef<R>&)>;
212
213 virtual ~IterativeSolver() = default;
214 IterativeSolver() = default;
218 IterativeSolver<R, Q, P>& operator=(IterativeSolver<R, Q, P>&&) noexcept = default;
219
247 virtual bool solve(const VecRef<R>& parameters, const VecRef<R>& actions, const Problem<R>& problem,
248 bool generate_initial_guess = false) = 0;
249 virtual bool solve(R& parameters, R& actions, const Problem<R>& problem, bool generate_initial_guess = false) = 0;
250 virtual bool solve(std::vector<R>& parameters, std::vector<R>& actions, const Problem<R>& problem,
251 bool generate_initial_guess = false) = 0;
252
263 virtual int add_vector(const VecRef<R>& parameters, const VecRef<R>& actions) = 0;
264
265 // FIXME this should be removed in favour of VecRef interface
266 virtual int add_vector(std::vector<R>& parameters, std::vector<R>& action) = 0;
267 virtual int add_vector(R& parameters, R& action, value_type value = 0) = 0;
268
283 virtual size_t add_p(const CVecRef<P>& pparams, const array::Span<value_type>& pp_action_matrix,
284 const VecRef<R>& parameters, const VecRef<R>& action, fapply_on_p_type apply_p) = 0;
285
286 // FIXME Is this needed?
287 virtual void clearP() = 0;
288
290 virtual void solution(const std::vector<int>& roots, const VecRef<R>& parameters, const VecRef<R>& residual) = 0;
291
293 virtual void solution_params(const std::vector<int>& roots, const VecRef<R>& parameters) = 0;
294
296 virtual size_t end_iteration(const VecRef<R>& parameters, const VecRef<R>& residual) = 0;
297
301 virtual bool end_iteration_needed() = 0;
302
313 virtual std::vector<size_t> suggest_p(const CVecRef<R>& solution, const CVecRef<R>& residual, size_t max_number,
314 double threshold) = 0;
315
316 virtual void solution(const std::vector<int>& roots, std::vector<R>& parameters, std::vector<R>& residual) = 0;
317 virtual void solution(R& parameters, R& residual) = 0;
318 virtual void solution_params(const std::vector<int>& roots, std::vector<R>& parameters) = 0;
319 virtual void solution_params(R& parameters) = 0;
320 virtual size_t end_iteration(std::vector<R>& parameters, std::vector<R>& action) = 0;
321 virtual size_t end_iteration(R& parameters, R& action) = 0;
322
326 virtual const std::vector<int>& working_set() const = 0;
329 virtual std::vector<scalar_type> working_set_eigenvalues() const {
330 return std::vector<scalar_type>(working_set().size(), 0);
331 }
334 virtual size_t n_roots() const = 0;
335 virtual void set_n_roots(size_t nroots) = 0;
336 virtual const std::vector<scalar_type>& errors() const = 0;
337 virtual const Statistics& statistics() const = 0;
339 virtual void report(std::ostream& cout, bool endl = true) const = 0;
341 virtual void report() const = 0;
342
344 virtual void set_convergence_threshold(double thresh) = 0;
346 virtual double convergence_threshold() const = 0;
348 virtual void set_convergence_threshold_value(double thresh) = 0;
350 virtual double convergence_threshold_value() const = 0;
351 virtual void set_verbosity(Verbosity v) = 0;
352 virtual void set_verbosity(int v) = 0;
353 virtual Verbosity get_verbosity() const = 0;
354 virtual void set_max_iter(int n) = 0;
355 virtual int get_max_iter() const = 0;
356 virtual void set_max_p(int n) = 0;
357 virtual int get_max_p() const = 0;
358 virtual void set_p_threshold(double thresh) = 0;
359 virtual double get_p_threshold() const = 0;
360 virtual const subspace::Dimensions& dimensions() const = 0;
361 // FIXME Missing parameters: SVD threshold
364 virtual void set_options(const Options& options) = 0;
367 virtual std::shared_ptr<Options> get_options() const = 0;
372 virtual scalar_type value() const = 0;
377 virtual bool nonlinear() const = 0;
383 virtual const std::shared_ptr<molpro::profiler::Profiler>& profiler() const = 0;
392 virtual bool test_problem(const Problem<R>& problem, R& v0, R& v1, int verbosity = 0,
393 double threshold = 1e-5) const = 0;
394};
395
400template <class R, class Q, class P>
401class LinearEigensystem : public IterativeSolver<R, Q, P> {
402public:
405 virtual std::vector<scalar_type> eigenvalues() const = 0;
407 virtual void set_hermiticity(bool hermitian) = 0;
409 virtual bool get_hermiticity() const = 0;
410};
411
412template <class R, class Q, class P>
413class LinearEquations : public IterativeSolver<R, Q, P> {
414public:
416 virtual void add_equations(const CVecRef<R>& rhs) = 0;
417 virtual void add_equations(const std::vector<R>& rhs) = 0;
418 virtual void add_equations(const R& rhs) = 0;
419 virtual CVecRef<Q> rhs() const = 0;
421 virtual void set_hermiticity(bool hermitian) = 0;
423 virtual bool get_hermiticity() const = 0;
424};
425
427template <class R, class Q, class P>
428class Optimize : public IterativeSolver<R, Q, P> {};
429
431template <class R, class Q, class P>
432class NonLinearEquations : public IterativeSolver<R, Q, P> {};
433
434} // namespace molpro::linalg::itsolv
435
436#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:200
typename R::value_type value_type
The underlying type of elements of vectors.
Definition: IterativeSolver.h:202
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:205
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:204
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:211
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:208
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:329
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_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:401
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:413
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
Solves non-linear system of equations using methods such as DIIS.
Definition: IterativeSolver.h:432
Optimises to a stationary point using methods such as L-BFGS.
Definition: IterativeSolver.h:428
Abstract class defining the problem-specific interface for the simplified solver interface to Iterati...
Definition: IterativeSolver.h:77
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:100
R container_t
Definition: IterativeSolver.h:81
virtual std::vector< double > pp_action_matrix(const std::vector< P > &pparams) const
Calculate the kernel matrix in the P space.
Definition: IterativeSolver.h:153
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:123
typename R::value_type value_t
Definition: IterativeSolver.h:82
virtual bool diagonals(container_t &d) const
Optionally provide the diagonal elements of the underlying kernel. If implemented and returning true,...
Definition: IterativeSolver.h:112
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:165
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:92
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:180
virtual bool RHS(R &RHS, unsigned int instance) const
Return the inhomogeneous part of a linear equation system.
Definition: IterativeSolver.h:146
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:135
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition: helper.h:10
void precondition_default(const VecRef< T > &action, const std::vector< double > &shift, const T &diagonals)
Definition: IterativeSolver.h:35
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:23
static constexpr bool value
Definition: IterativeSolver.h:30
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:5