iterative-solver 0.0
 
Loading...
Searching...
No Matches
NonLinearEquationsDIIS.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_NONLINEAREQUATIONSDIIS_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_NONLINEAREQUATIONSDIIS_H
3#include <Eigen/Core>
4#include <Eigen/Eigenvalues>
5#include <algorithm>
6#include <cmath>
7#include <limits>
8#include <molpro/linalg/itsolv/CastOptions.h>
9#include <molpro/linalg/itsolv/DSpaceResetter.h>
10#include <molpro/linalg/itsolv/IterativeSolverTemplate.h>
11#include <molpro/linalg/itsolv/propose_rspace.h>
12#include <molpro/linalg/itsolv/subspace/Matrix.h>
13#include <molpro/linalg/itsolv/subspace/SubspaceSolverDIIS.h>
14#include <molpro/linalg/itsolv/subspace/XSpace.h>
15#include <molpro/profiler/Profiler.h>
16
17namespace molpro::linalg::itsolv {
26template <class R, class Q = R, class P = std::map<size_t, typename R::value_type>>
27class NonLinearEquationsDIIS : public IterativeSolverTemplate<NonLinearEquations, R, Q, P> {
28 bool m_converged;
29
30public:
33 using typename SolverTemplate::scalar_type;
34 using typename SolverTemplate::value_type;
35 using typename SolverTemplate::value_type_abs;
36
37 explicit NonLinearEquationsDIIS(const std::shared_ptr<ArrayHandlers<R, Q, P>>& handlers,
38 const std::shared_ptr<Logger>& logger_ = std::make_shared<Logger>())
39 : SolverTemplate(std::make_shared<subspace::XSpace<R, Q, P>>(handlers, logger_),
40 std::static_pointer_cast<subspace::ISubspaceSolver<R, Q, P>>(
41 std::make_shared<subspace::SubspaceSolverDIIS<R, Q, P>>(logger_, m_converged)),
42 handlers, std::make_shared<Statistics>(), logger_), m_converged(false) {
43 auto xspace = std::dynamic_pointer_cast<subspace::XSpace<R, Q, P>>(this->m_xspace);
44 xspace->set_hermiticity(true);
45 xspace->set_action_action();
46 }
47
48 bool nonlinear() const override { return true; }
49
50private:
52 std::pair<size_t, value_type_abs> least_important_vector(const subspace::Matrix<value_type>& H) {
53 using matrix_type = Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic>;
54 const auto He = Eigen::Map<const matrix_type>(H.data().data(), H.rows(), H.cols());
55 std::pair<size_t, value_type_abs> result{0, std::numeric_limits<value_type_abs>::max()};
56 if (He.cols() < 2)
57 return result;
58 auto evs = Eigen::SelfAdjointEigenSolver<matrix_type>();
59 evs.compute(He);
60 // std::cout << "Eigenvalues: "<<evs.eigenvalues().transpose()<<std::endl;
61 // std::cout << "Eigenvectors:\n"<<evs.eigenvectors()<<std::endl;
62 // result.first = He.cols() - 1;
63 // return result;
64 value_type_abs evmax = 0;
65 for (Eigen::Index i = 0; i < He.cols(); ++i) {
66 evmax = std::max(evmax, evs.eigenvalues()(i));
67 if (evs.eigenvalues()(i) < result.second) {
68 result.second = evs.eigenvalues()(i);
69 result.first = 1;
70 for (Eigen::Index j = 1; j < He.rows(); ++j) {
71 if (std::abs(evs.eigenvectors().col(i)(j)) > std::abs(evs.eigenvectors().col(i)(result.first)))
72 result.first = j;
73 }
74 }
75 }
76 result.second /= evmax;
77 if (result.second > m_svd_thresh)
78 result = {size_t(He.cols() - 1), std::numeric_limits<value_type_abs>::max()};
79 // std::cout << "least important vector " << result.first << " : " << result.second << std::endl;
80 return result;
81 }
82
83public:
84 // NB: this overrides the VecRef<R> overload of add_vector, not the single-R& overload, because that
85 // is the one actually reached from IterativeSolverAddVector (via the std::vector<R>& overload, which
86 // forwards to this one). The single-R& and std::vector<R>& overloads are left to their inherited
87 // IterativeSolverTemplate implementations, which forward here through virtual dispatch. Previously the
88 // Q-space pruning below (which enforces max_size_qspace) lived in the single-R& overload only, so it
89 // was never executed and the Q space grew without bound.
90 int add_vector(const VecRef<R>& parameters, const VecRef<R>& actions) override {
91 auto prof = this->profiler()->push("itsolv::add_vector");
92 auto& residual = actions.front().get();
93 const value_type_abs error = std::sqrt(std::abs(this->m_handlers->rr().dot(residual, residual)));
94 m_converged = error < this->m_convergence_threshold;
95 using namespace subspace;
96 auto& xspace = this->m_xspace;
97 const auto& H = xspace->data[EqnData::H];
98 // std::cout << "H " << as_string(H) << std::endl;
99 for (std::pair<size_t, value_type_abs> deleter = least_important_vector(H);
100 xspace->size() >= size_t(this->m_max_size_qspace) or deleter.second < m_svd_thresh;
101 deleter = least_important_vector(H)) {
102 // std::cout << "deleter " << deleter.first << " : " << deleter.second << std::endl;
103 xspace->eraseq(deleter.first);
104 }
105 // std::cout << "H after delete Q "<<as_string(H)<<std::endl;
106
108 this->m_errors.front() = error;
109 return nwork;
110 }
111 size_t end_iteration(const VecRef<R>& parameters, const VecRef<R>& action) override {
112 auto prof = this->profiler()->push("itsolv::end_iteration");
113 this->solution_params(this->m_working_set, parameters);
114 this->m_end_iteration_needed = false;
115 if (this->m_errors.front() < this->m_convergence_threshold) {
116 this->m_working_set.clear();
117 return 0;
118 }
119 this->m_working_set.assign(1, 0);
120 bool precon = true; // TODO implement
121 if (precon) { // action is expected to hold the preconditioned residual, and here we should add it to parameters
122 this->m_handlers->rr().axpy(-1, action.front(), parameters.front());
123 } else { // residual not used, simply leave parameters alone
124 }
125 this->m_stats->iterations++;
126 return 1;
127 }
128
129 size_t end_iteration(std::vector<R>& parameters, std::vector<R>& action) override {
130 auto result = end_iteration(wrap(parameters), wrap(action));
131 // std::cout << ", max q" << this->m_max_size_qspace << std::endl; // get_max_size_qspace();
132 return result;
133 }
134
136 void set_norm_thresh(value_type_abs thresh) { m_norm_thresh = thresh; }
137 value_type_abs get_norm_thresh() const { return m_norm_thresh; }
140 void set_svd_thresh(value_type_abs thresh) { m_svd_thresh = thresh; }
141 value_type_abs get_svd_thresh() const { return m_svd_thresh; }
146
147 void set_options(const Options& options) override {
150 if (opt.max_size_qspace)
151 set_max_size_qspace(opt.max_size_qspace.value());
152 if (opt.norm_thresh)
153 set_norm_thresh(opt.norm_thresh.value());
154 if (opt.svd_thresh)
155 set_svd_thresh(opt.svd_thresh.value());
156 }
157
158 std::shared_ptr<Options> get_options() const override {
159 auto opt = std::make_shared<NonLinearEquationsDIISOptions>();
161 opt->max_size_qspace = get_max_size_qspace();
162 opt->norm_thresh = get_norm_thresh();
163 opt->svd_thresh = get_svd_thresh();
164 return opt;
165 }
166
167 void report(std::ostream& cout, bool endl = true) const override {
169 // auto& err = this->m_errors;
170 // std::copy(begin(err), end(err), std::ostream_iterator<value_type_abs>(cout, ", "));
171 // cout << std::defaultfloat;
172 // cout << ", max q" << this->m_max_size_qspace; // get_max_size_qspace();
173 // if (endl)
174 // cout << std::endl;
175 }
176
177 size_t end_iteration(R& parameters, R& actions) override {
178 auto wparams = std::vector<std::reference_wrapper<R>>{std::ref(parameters)};
179 auto wactions = std::vector<std::reference_wrapper<R>>{std::ref(actions)};
181 }
182
183protected:
184 // for non-linear problems, actions already contains the residual
185 void construct_residual(const std::vector<int>& roots, const CVecRef<R>& params, const VecRef<R>& actions) override {}
186
192};
193
194} // namespace molpro::linalg::itsolv
195#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_NONLINEAREQUATIONSDIIS_H
Class, containing a collection of array handlers used in IterativeSolver Provides a Builder sub-class...
Definition ArrayHandlers.h:25
Implements IterativeSolver interface that is common to all solvers.
Definition IterativeSolverTemplate.h:163
void solution_params(const std::vector< int > &roots, std::vector< R > &parameters) override
Definition IterativeSolverTemplate.h:267
std::vector< int > m_working_set
indices of roots in the working set
Definition IterativeSolverTemplate.h:698
std::shared_ptr< subspace::IXSpace< R, Q, P > > m_xspace
manages the subspace and associated data
Definition IterativeSolverTemplate.h:694
std::shared_ptr< ArrayHandlers< R, Q, P > > m_handlers
Array handlers.
Definition IterativeSolverTemplate.h:693
std::vector< value_type_abs > m_errors
errors from the most recent solution
Definition IterativeSolverTemplate.h:696
std::shared_ptr< Options > get_options() const override
Definition IterativeSolverTemplate.h:311
const std::shared_ptr< molpro::profiler::Profiler > & profiler() const override
Definition IterativeSolverTemplate.h:397
bool m_end_iteration_needed
whether end_iteration should be called after any preconditioner
Definition IterativeSolverTemplate.h:715
int add_vector(const VecRef< R > &parameters, const VecRef< R > &actions) override
Definition IterativeSolverTemplate.h:186
void report() const override
Definition IterativeSolverTemplate.h:352
void set_options(const Options &options) override
Definition IterativeSolverTemplate.h:296
std::shared_ptr< Statistics > m_stats
accumulates statistics of operations performed by the solver
Definition IterativeSolverTemplate.h:703
value_type_abs m_convergence_threshold
residual norms less than this mark a converged solution
Definition IterativeSolverTemplate.h:700
A class that optimises a function using a Quasi-Newton or other method.
Definition NonLinearEquationsDIIS.h:27
size_t end_iteration(R &parameters, R &actions) override
Definition NonLinearEquationsDIIS.h:177
value_type_abs get_svd_thresh() const
Definition NonLinearEquationsDIIS.h:141
NonLinearEquationsDIIS(const std::shared_ptr< ArrayHandlers< R, Q, P > > &handlers, const std::shared_ptr< Logger > &logger_=std::make_shared< Logger >())
Definition NonLinearEquationsDIIS.h:37
value_type_abs m_svd_thresh
svd values smaller than this mark the null space (rescaled to the working precision)
Definition NonLinearEquationsDIIS.h:190
value_type_abs m_norm_thresh
vectors with norm less than threshold can be considered null (rescaled to the working precision)
Definition NonLinearEquationsDIIS.h:188
void set_svd_thresh(value_type_abs thresh)
Definition NonLinearEquationsDIIS.h:140
size_t end_iteration(std::vector< R > &parameters, std::vector< R > &action) override
Definition NonLinearEquationsDIIS.h:129
size_t end_iteration(const VecRef< R > &parameters, const VecRef< R > &action) override
Definition NonLinearEquationsDIIS.h:111
int get_max_size_qspace() const
Definition NonLinearEquationsDIIS.h:145
bool nonlinear() const override
Definition NonLinearEquationsDIIS.h:48
int add_vector(const VecRef< R > &parameters, const VecRef< R > &actions) override
Definition NonLinearEquationsDIIS.h:90
void construct_residual(const std::vector< int > &roots, const CVecRef< R > &params, const VecRef< R > &actions) override
Constructs residual for given roots provided their parameters and actions.
Definition NonLinearEquationsDIIS.h:185
void report(std::ostream &cout, bool endl=true) const override
Definition NonLinearEquationsDIIS.h:167
std::shared_ptr< Options > get_options() const override
Definition NonLinearEquationsDIIS.h:158
int m_max_size_qspace
maximum size of Q space
Definition NonLinearEquationsDIIS.h:191
void set_norm_thresh(value_type_abs thresh)
Set threshold on the norm of parameters that should be considered null.
Definition NonLinearEquationsDIIS.h:136
void set_max_size_qspace(int n)
Definition NonLinearEquationsDIIS.h:144
value_type_abs get_norm_thresh() const
Definition NonLinearEquationsDIIS.h:137
void set_options(const Options &options) override
Definition NonLinearEquationsDIIS.h:147
Matrix container that allows simple data access, slicing, copying and resizing without loosing data.
Definition Matrix.h:32
const std::vector< T > & data() const &
Access the underlying data buffer.
Definition Matrix.h:69
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition helper.h:14
std::unique_ptr< LinearEigensystem< R, Q, P > > create_LinearEigensystem(const LinearEigensystemOptions &options, const std::shared_ptr< ArrayHandlers< R, Q, P > > &handlers=std::make_shared< molpro::linalg::itsolv::ArrayHandlers< R, Q, P > >())
Definition SolverFactory.h:111
auto wrap(ForwardIt begin, ForwardIt end)
Takes a begin and end iterators and returns a vector of references to each element.
Definition wrap.h:32
std::vector< std::reference_wrapper< const A > > CVecRef
Definition wrap.h:14
std::vector< std::reference_wrapper< A > > VecRef
Definition wrap.h:11
const std::shared_ptr< const molpro::Options > options()
Get the Options object associated with iterative-solver.
Definition linalg_options.cpp:4
static std::shared_ptr< NonLinearEquationsDIISOptions > NonLinearEquationsDIIS(const std::shared_ptr< Options > &options)
Definition CastOptions.h:67
Access point for different options in iterative solvers.
Definition Options.h:20
Information about performance of IterativeSolver instance.
Definition Statistics.h:10