iterative-solver 0.0
LinearEigensystemRSPT.h
1//
2// Created by Peter Knowles on 18/01/2021.
3//
4
5#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_LINEAREIGENSYSTEMRSPT_H_
6#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_LINEAREIGENSYSTEMRSPT_H_
7
8#include <iterator>
9//#include <molpro/linalg/array/DistrArraySpan.h>
10#include <molpro/linalg/itsolv/CastOptions.h>
11#include <molpro/linalg/itsolv/DSpaceResetter.h>
12#include <molpro/linalg/itsolv/IterativeSolverTemplate.h>
13#include <molpro/linalg/itsolv/LinearEigensystemRSPTOptions.h>
14#include <molpro/linalg/itsolv/Logger.h>
15#include <molpro/linalg/itsolv/propose_rspace.h>
16#include <molpro/linalg/itsolv/subspace/SubspaceSolverRSPT.h>
17#include <molpro/linalg/itsolv/subspace/XSpace.h>
18
19namespace molpro::linalg::itsolv {
20
32template <class R, class Q = R, class P = std::map<size_t, typename R::value_type>>
33class LinearEigensystemRSPT : public IterativeSolverTemplate<LinearEigensystem, R, Q, P> {
34public:
36 using typename SolverTemplate::scalar_type;
38
39 explicit LinearEigensystemRSPT(const std::shared_ptr<ArrayHandlers<R, Q, P>>& handlers,
40 const std::shared_ptr<Logger>& logger_ = std::make_shared<Logger>())
41 : SolverTemplate(std::make_shared<subspace::XSpace<R, Q, P>>(handlers, logger_),
42 std::static_pointer_cast<subspace::ISubspaceSolver<R, Q, P>>(
43 std::make_shared<subspace::SubspaceSolverRSPT<R, Q, P>>(logger_)),
44 handlers, std::make_shared<Statistics>(), logger_),
45 logger(logger_) {
46 // set_hermiticity(true);
47 auto xspace = std::dynamic_pointer_cast<subspace::XSpace<R, Q, P>>(this->m_xspace);
48 xspace->set_hermiticity(true);
49 auto subspace_solver = std::dynamic_pointer_cast<subspace::SubspaceSolverRSPT<R, Q, P>>(this->m_subspace_solver);
50 subspace_solver->set_hermiticity(true);
51 this->set_n_roots(1);
52 this->m_normalise_solution = false;
53 }
54
55 bool nonlinear() const override { return false; }
56
57 bool linearEigensystem() const override { return true; }
58
66 size_t end_iteration(const VecRef<R>& parameters, const VecRef<R>& action) override {
67 return end_iteration(parameters.front().get(), action.front().get());
68 }
69 size_t end_iteration(std::vector<R>& parameters, std::vector<R>& action) override {
70 return end_iteration(parameters.front(), action.front());
71 }
72 size_t end_iteration(R& parameters, R& actions) override {
73 auto n = this->m_xspace->size();
74 if (n == 1)
75 this->m_handlers->rr().fill(0, parameters);
76 this->m_handlers->rr().axpy(-1, actions, parameters);
77
78 this->m_end_iteration_needed = false;
79 return this->m_errors.front() < this->m_convergence_threshold ? 0 : 1;
80 }
81
83 void precondition(std::vector<R>& parameters, std::vector<R>& action) const {}
84
85 std::vector<scalar_type> eigenvalues() const override { return this->m_subspace_solver->eigenvalues(); }
86
87 virtual std::vector<scalar_type> working_set_eigenvalues() const override {
88 auto eval = std::vector<scalar_type>{};
89 for (auto i : this->working_set()) {
90 eval.emplace_back(this->m_subspace_solver->eigenvalues().at(i));
91 }
92 return eval;
93 }
94
95 // void set_value_errors() override {
96 // auto current_values = this->m_subspace_solver->eigenvalues();
97 // this->m_value_errors.assign(current_values.size(), std::numeric_limits<scalar_type>::max());
98 // for (size_t i = 0; i < std::min(m_last_values.size(), current_values.size()); i++)
99 // this->m_value_errors[i] = std::abs(current_values[i] - m_last_values[i]);
100 // if (!m_resetting_in_progress)
101 // m_last_values = current_values;
102 // }
103
104 void report(std::ostream& cout, bool endl = true) const override {
105 // SolverTemplate::report(cout);
106 // cout << "errors " << std::scientific;
107 // auto& err = this->m_errors;
108 // std::copy(begin(err), end(err), std::ostream_iterator<scalar_type>(molpro::cout, ", "));
109 // cout << std::endl;
110 // cout << "eigenvalues ";
111 // auto ev = eigenvalues();
112 cout << "Perturbed energies ";
113 cout << std::fixed << std::setprecision(8);
114 std::copy(begin(m_rspt_values), end(m_rspt_values), std::ostream_iterator<scalar_type>(molpro::cout, ", "));
115 cout << std::defaultfloat;
116 if (endl)
117 cout << std::endl;
118 }
119
120 void set_hermiticity(bool hermitian) override {
121 // m_hermiticity = hermitian;
122 auto xspace = std::dynamic_pointer_cast<subspace::XSpace<R, Q, P>>(this->m_xspace);
123 xspace->set_hermiticity(hermitian);
124 auto subspace_solver = std::dynamic_pointer_cast<subspace::SubspaceSolverRSPT<R, Q, P>>(this->m_subspace_solver);
125 subspace_solver->set_hermiticity(hermitian);
126 }
127
128 bool get_hermiticity() const override { return true; }
129
130 void set_options(const Options& options) override {
133 if (opt.norm_thresh)
134 propose_rspace_norm_thresh = opt.norm_thresh.value();
135 if (opt.svd_thresh)
136 propose_rspace_svd_thresh = opt.svd_thresh.value();
137 }
138
139 std::shared_ptr<Options> get_options() const override {
140 auto opt = std::make_shared<LinearEigensystemRSPTOptions>();
141 opt->copy(*SolverTemplate::get_options());
142 opt->norm_thresh = propose_rspace_norm_thresh;
143 opt->svd_thresh = propose_rspace_svd_thresh;
144 return opt;
145 }
146
147 std::shared_ptr<Logger> logger;
152protected:
153 // static std::string str(const array::DistrArraySpan& a) {
154 // std::vector<double> v(a.size());
155 // a.get(0, a.size(), v.data());
156 // return str(v);
157 // }
158 static std::string str(const std::vector<double>& a) {
159 std::string result;
160 for (const auto& e : a)
161 result += std::to_string(e) + " ";
162 return result;
163 }
164 void construct_residual(const std::vector<int>& roots, const CVecRef<R>& params, const VecRef<R>& actions) override {
165 auto prof = this->profiler()->push("itsolv::construct_residual");
166 auto xspace = std::dynamic_pointer_cast<subspace::XSpace<R, Q, P>>(this->m_xspace);
167 const auto& q = xspace->paramsq();
168 const auto& n = q.size();
169 const auto& c = params.back();
170 auto& hc = actions.back();
171 // molpro::cout << "construct_residual n=" << n << std::endl;
172 // molpro::cout << "construct_residual c=" << str(c) << std::endl;
173 // molpro::cout << "construct_residual hc=" << str(hc) << std::endl;
174 // for (auto i = 0; i < n; i++)
175 // molpro::cout << "construct_residual q[" << i << "].dot(c)=" << this->m_handlers->qr().dot(q.at(i), c)
176 // << std::endl;
177 // for (auto i = 0; i < n; i++)
178 // molpro::cout << "construct_residual q[" << i << "].dot(hc)=" << this->m_handlers->qr().dot(q.at(i), hc)
179 // << std::endl;
180 // q.at(k) holds psi(n-k-1)
181 if (n == 1)
182 m_rspt_values.assign(1, 0);
183 m_rspt_values.push_back(this->m_handlers->qr().dot(q.at(n - 1), hc));
184 // molpro::cout << "m_rspt_values[" << m_rspt_values.size() - 1 << "]=" << m_rspt_values.back() << std::endl;
185 // molpro::cout << "m_rspt_values " << str(m_rspt_values)<<std::endl;
186 this->m_handlers->rr().axpy(-m_rspt_values[0], c, hc);
187 for (size_t k = 0; k < n; k++) {
188 // molpro::cout << "axpy E[" << n - k << "] c[" << k << "]" << std::endl;
189 this->m_handlers->rq().axpy(-m_rspt_values[n - k], q.at(n - k - 1), hc);
190 }
191 }
192
193 std::vector<double> m_rspt_values;
194};
195
196} // namespace molpro::linalg::itsolv
197
198#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_LINEAREIGENSYSTEMRSPT_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:127
std::shared_ptr< subspace::IXSpace< R, R, std::map< size_t, typename R::value_type > > > m_xspace
manages the subspace and associated data
Definition: IterativeSolverTemplate.h:579
std::shared_ptr< ArrayHandlers< R, R, std::map< size_t, typename R::value_type > > > m_handlers
Array handlers.
Definition: IterativeSolverTemplate.h:578
std::shared_ptr< subspace::ISubspaceSolver< R, R, std::map< size_t, typename R::value_type > > > m_subspace_solver
solves the subspace problem
Definition: IterativeSolverTemplate.h:580
std::shared_ptr< Options > get_options() const override
Definition: IterativeSolverTemplate.h:262
const std::shared_ptr< molpro::profiler::Profiler > & profiler() const override
Definition: IterativeSolverTemplate.h:320
bool m_end_iteration_needed
whether end_iteration should be called after any preconditioner
Definition: IterativeSolverTemplate.h:600
void report() const override
Writes a report to std::cout.
Definition: IterativeSolverTemplate.h:287
bool m_normalise_solution
whether to normalise the solutions
Definition: IterativeSolverTemplate.h:590
double m_convergence_threshold
residual norms less than this mark a converged solution
Definition: IterativeSolverTemplate.h:585
const std::vector< int > & working_set() const override
Working set of roots that are not yet converged.
Definition: IterativeSolverTemplate.h:243
void set_options(const Options &options) override
Definition: IterativeSolverTemplate.h:253
std::vector< double > m_errors
errors from the most recent solution
Definition: IterativeSolverTemplate.h:581
One specific implementation of LinearEigensystem using Davidson's algorithm with modifications to man...
Definition: LinearEigensystemRSPT.h:33
void set_hermiticity(bool hermitian) override
Sets hermiticity of kernel.
Definition: LinearEigensystemRSPT.h:120
std::shared_ptr< Options > get_options() const override
Definition: LinearEigensystemRSPT.h:139
void set_options(const Options &options) override
Definition: LinearEigensystemRSPT.h:130
bool get_hermiticity() const override
Gets hermiticity of kernel, if true than it is hermitian, otherwise it is not.
Definition: LinearEigensystemRSPT.h:128
size_t end_iteration(std::vector< R > &parameters, std::vector< R > &action) override
Definition: LinearEigensystemRSPT.h:69
bool linearEigensystem() const override
Definition: LinearEigensystemRSPT.h:57
double propose_rspace_svd_thresh
Definition: LinearEigensystemRSPT.h:149
double propose_rspace_norm_thresh
vectors with norm less than threshold can be considered null.
Definition: LinearEigensystemRSPT.h:148
void report(std::ostream &cout, bool endl=true) const override
Writes a report to cout output stream.
Definition: LinearEigensystemRSPT.h:104
std::vector< double > m_rspt_values
perturbation series for the eigenvalue
Definition: LinearEigensystemRSPT.h:193
std::vector< scalar_type > eigenvalues() const override
The calculated eigenvalues of the subspace matrix.
Definition: LinearEigensystemRSPT.h:85
bool nonlinear() const override
Report whether the class is a non-linear solver.
Definition: LinearEigensystemRSPT.h:55
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: LinearEigensystemRSPT.h:164
size_t end_iteration(const VecRef< R > &parameters, const VecRef< R > &action) override
constructs next perturbed wavefunction
Definition: LinearEigensystemRSPT.h:66
virtual std::vector< scalar_type > working_set_eigenvalues() const override
Definition: LinearEigensystemRSPT.h:87
static std::string str(const std::vector< double > &a)
Definition: LinearEigensystemRSPT.h:158
void precondition(std::vector< R > &parameters, std::vector< R > &action) const
Applies the Davidson preconditioner.
Definition: LinearEigensystemRSPT.h:83
size_t end_iteration(R &parameters, R &actions) override
Definition: LinearEigensystemRSPT.h:72
LinearEigensystemRSPT(const std::shared_ptr< ArrayHandlers< R, Q, P > > &handlers, const std::shared_ptr< Logger > &logger_=std::make_shared< Logger >())
Definition: LinearEigensystemRSPT.h:39
std::shared_ptr< Logger > logger
Definition: LinearEigensystemRSPT.h:147
Interface for a specific iterative solver, it can add special member functions or variables.
Definition: IterativeSolver.h:401
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition: helper.h:10
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: options.cpp:4
static const LinearEigensystemRSPTOptions & LinearEigensystemRSPT(const Options &options)
Definition: CastOptions.h:45
Access point for different options in iterative solvers.
Definition: Options.h:20
Information about performance of IterativeSolver instance.
Definition: Statistics.h:10