1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_ITERATIVESOLVERTEMPLATE_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_ITERATIVESOLVERTEMPLATE_H
3#include <molpro/Profiler.h>
4#include <molpro/iostream.h>
5#include <molpro/linalg/itsolv/IterativeSolver.h>
6#include <molpro/linalg/itsolv/Logger.h>
7#include <molpro/linalg/itsolv/subspace/ISubspaceSolver.h>
8#include <molpro/linalg/itsolv/subspace/IXSpace.h>
9#include <molpro/linalg/itsolv/subspace/Matrix.h>
10#include <molpro/linalg/itsolv/subspace/util.h>
11#include <molpro/linalg/itsolv/util.h>
12#include <molpro/linalg/itsolv/wrap.h>
13#include <molpro/profiler/Profiler.h>
26 auto batches = std::vector<std::pair<size_t, size_t>>{};
37template <
class R,
class Q,
class P,
typename value_type>
40 const std::vector<std::reference_wrapper<P>>&
pparams,
41 const std::vector<std::reference_wrapper<Q>>&
qparams,
42 const std::vector<std::reference_wrapper<Q>>&
dparams,
size_t oP,
size_t oQ,
size_t oD,
45 prof->start(
"get rd_mat");
49 for (
size_t i = 0;
i <
roots.size(); ++
i) {
54 for (
size_t i = 0;
i <
roots.size(); ++
i) {
73 const size_t oP,
const size_t nP) {
74 auto vectorP = std::vector<std::vector<T>>{};
75 for (
auto root :
roots) {
76 vectorP.emplace_back();
77 for (
size_t j = 0;
j < nP; ++
j)
78 vectorP.back().push_back(solutions(root, oP +
j));
86 assert(params.size() >= n_roots && actions.size() >= n_roots);
89 for (
size_t i = 0;
i < n_roots; ++
i) {
91 std::sqrt(std::abs(handler.
dot(params.at(
i), params.at(
i))));
92 if (dot > norm_thresh) {
93 handler.
scal(1. / dot, params.at(
i));
94 handler.
scal(1. / dot, actions.at(
i));
96 logger.
warn(
"solution parameter's length is too small, dot = " + std::format(
"{:.2e}",
double(dot)));
101template <
class R,
typename T>
103 assert(residual.size() >= errors.size());
104 for (
size_t i = 0;
i < errors.size(); ++
i) {
105 auto a = handler.
dot(residual[
i], residual[
i]);
106 errors[
i] = std::sqrt(std::abs(
a));
113 auto ordered_errors = std::multimap<T, size_t, std::greater<T>>{};
114 for (
size_t i = 0;
i < errors.size(); ++
i) {
118 auto working_set = std::vector<int>{};
120 std::transform(begin(
ordered_errors), end, std::back_inserter(working_set), [](
const auto&
el) {
return el.second; });
121 std::sort(working_set.begin(), working_set.end());
133 static constexpr const char *
name =
"NewIteration";
134 static constexpr std::size_t
iter = 0;
143 static constexpr const char *
name =
"IterationReport";
151 static constexpr const char *
name =
"SummaryReport";
162template <
template <
class,
class,
class>
class Solver,
class R,
class Q,
class P>
165 using typename Solver<R, Q, P>::fapply_on_p_type;
166 using typename Solver<R, Q, P>::scalar_type;
167 using typename Solver<R, Q, P>::value_type;
168 using typename Solver<R, Q, P>::value_type_abs;
169 using typename Solver<R, Q, P>::VectorP;
187 auto outer =
profiler()->push(
"itsolv::add_vector");
189 m_logger->trace(
"IterativeSolverTemplate::add_vector iteration = ",
m_stats->iterations);
190 m_logger->debug(
"IterativeSolverTemplate::add_vector size of {params, actions, working_set} = ",
193 throw std::runtime_error(
194 "Solver contains P space but no valid apply_p function. Make sure add_p was called correctly.");
199 prof->start(
"update_qspace");
203 prof->start(
"solve_and_generate_working_set");
211 int add_vector(std::vector<R>& parameters, std::vector<R>& actions)
override {
221 auto prof =
profiler()->push(
"itsolv::add_p");
223 throw std::runtime_error(
"P space must be empty or at least as large as number of roots sought");
238 prof->start(
"construct_solution (parameters)");
243 prof->start(
"construct_solution (residual)");
248 prof->start(
"apply");
260 void solution(
const std::vector<int>&
roots, std::vector<R>& parameters, std::vector<R>& residual)
override {
263 void solution(R& parameters, R& residual)
override {
299 if (
options.convergence_threshold)
312 auto options = std::make_shared<Options>();
333 cout <<
", |residual| = ";
389 scalar_type
value()
const override {
391 :
nan(
"molpro::linalg::itsolv::IterativeSolver::value");
395 m_profiler = std::shared_ptr<molpro::profiler::Profiler>(&
profiler);
397 const std::shared_ptr<molpro::profiler::Profiler>&
profiler()
const override {
return m_profiler; }
401 if (parameters.empty())
402 throw std::runtime_error(
"Empty container passed to IterativeSolver::solve()");
403 if (parameters.size() != actions.size())
404 throw std::runtime_error(
"Inconsistent container sizes in IterativeSolver::solve()");
411 this->
m_logger->enable_data_dumps(
true);
414 std::unique_ptr<Q> diagonals;
416 diagonals.reset(
new Q{
m_handlers->qr().copy(actions.at(0))});
420 throw std::runtime_error(
"Default initial guess requested, but diagonal elements are not available");
424 this->
m_logger->info(
"Initial guess generated from diagonal elements");
426 for (
const auto&
g :
guess) {
427 m_handlers->rp().copy(parameters[root], P{{
g.first, 1}});
429 m_logger->debug(
"-> initial guess with index ",
g.first);
434 int nwork = parameters.size();
435 std::vector<P> pspace;
443 [](
const auto&
a,
const auto&
b) {
444 return real_part(a.second) < real_part(b.second);
459 this->
m_logger->debug(std::format(
"P space element {}: {:.6e}",
s.first,
double(
real_part(
s.second))));
463 pspace.emplace_back((P){{
s.first, 1}});
464 fapply_on_p_type
apply_on_p = [&problem](
const std::vector<std::vector<value_type>>&
pcoeff,
472 for (
auto iter = 0; iter < this->
m_max_iter && nwork > 0; iter++) {
477 if (this->nonlinear()) {
478 value = problem.
residual(*parameters.begin(), *actions.begin());
480 }
else if (iter > 0
or pspace.empty()) {
482 wrap(actions.begin(), actions.begin() +
nwork));
489 m_handlers->rq().copy(parameters.at(0), *diagonals);
495 nwork = this->end_iteration(parameters, actions);
511 this->
m_logger->info(
"Solver converged");
518 auto wparams = std::vector<std::reference_wrapper<R>>{std::ref(parameters)};
519 auto wactions = std::vector<std::reference_wrapper<R>>{std::ref(actions)};
522 bool solve(std::vector<R>& parameters, std::vector<R>& actions,
const Problem<R>& problem,
529 value_type_abs
step = 1
e-4;
530 if (this->nonlinear()) {
535 std::cout <<
"value0 " <<
value0 << std::endl;
559 value_type(12 *
step);
576 std::cout <<
"Length of residual: " <<
norm2_residual <<
", scaling defect: " <<
norm2 << std::endl;
586 std::shared_ptr<Logger>
logger)
589 m_profiler_saved_depth(m_profiler->get_max_depth()) {
598 if (molpro::mpi::rank_global() == 0) {
599 auto file =
options()->parameter(
"PROFILER_OUTPUT",
"");
601 std::find_if(
file.begin(),
file.end(), [](
unsigned char ch) { return !std::isspace(ch); }) !=
file.end())
604 if (molpro::mpi::rank_global() == 0) {
605 auto file =
options()->parameter(
"PROFILER_DOTGRAPH",
"");
607 std::find_if(
file.begin(),
file.end(), [](
unsigned char ch) { return !std::isspace(ch); }) !=
file.end())
610 }
catch (
const std::exception&
e) {
611 std::cerr <<
"~IterativeSolverTemplate: failed to write profiler output: " <<
e.what() << std::endl;
613 std::cerr <<
"~IterativeSolverTemplate: failed to write profiler output" << std::endl;
634 auto p = prof->push(
"itsolv::solve_and_generate_working_set");
635 prof->start(
"itsolv::solve");
638 prof->start(
"itsolv::temp_solutions");
647 auto errors = std::vector<value_type_abs>(
roots.size(), 0);
650 for (
size_t i = 0;
i <
roots.size(); ++
i)
668 throw std::logic_error(
"incorrect ordering of roots");
669 if (root >
i && root < parameters.size()) {
670 m_handlers->rr().copy(parameters[
i], parameters[root]);
679 template <
typename TTT>
682 throw std::runtime_error(
"asking for more roots than parameters");
683 if (!
roots.empty() &&
685 throw std::runtime_error(
"asking for more roots than there are solutions");
694 std::shared_ptr<subspace::IXSpace<R, Q, P>>
m_xspace;
702 std::numeric_limits<value_type_abs>::max()};
712 mutable std::shared_ptr<molpro::profiler::Profiler> m_profiler;
713 int m_profiler_saved_depth;
Enhances various operations between pairs of arrays and allows dynamic code injection with uniform in...
Definition ArrayHandler.h:163
virtual value_type dot(const AL &x, const AR &y)=0
The hermitian inner product <x|y>: conjugate-linear in x, linear in y.
virtual void scal(value_type alpha, AL &x)=0
decltype(check_abs< value_type >()) value_type_abs
Definition ArrayHandler.h:183
Non-owning container taking a pointer to the data buffer and its size and exposing routines for itera...
Definition Span.h:31
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
std::vector< value_type_abs > m_value_errors
value errors from the most recent solution
Definition IterativeSolverTemplate.h:697
void set_convergence_threshold(value_type_abs thresh) override
Definition IterativeSolverTemplate.h:357
void iteration_report() const
Definition IterativeSolverTemplate.h:340
void set_profiler(molpro::profiler::Profiler &profiler) override
Definition IterativeSolverTemplate.h:394
std::optional< Verbosity > m_verbosity
how much output to print in solve()
Definition IterativeSolverTemplate.h:707
value_type_abs m_p_threshold
threshold for selecting P space
Definition IterativeSolverTemplate.h:710
size_t add_p(const CVecRef< P > &pparams, const array::Span< value_type > &pp_action_matrix, const VecRef< R > ¶meters, const VecRef< R > &actions, fapply_on_p_type apply_p) override
Definition IterativeSolverTemplate.h:219
value_type_abs convergence_threshold_value() const override
Definition IterativeSolverTemplate.h:360
int get_max_iter() const override
Definition IterativeSolverTemplate.h:382
void solution_params(const std::vector< int > &roots, std::vector< R > ¶meters) override
Definition IterativeSolverTemplate.h:267
void report(std::ostream &cout, bool endl=true) const override
Definition IterativeSolverTemplate.h:326
std::vector< int > m_working_set
indices of roots in the working set
Definition IterativeSolverTemplate.h:698
value_type_abs convergence_threshold() const override
Definition IterativeSolverTemplate.h:358
void summary_report() const
Definition IterativeSolverTemplate.h:346
scalar_type value() const override
Definition IterativeSolverTemplate.h:389
std::shared_ptr< subspace::IXSpace< R, Q, P > > m_xspace
manages the subspace and associated data
Definition IterativeSolverTemplate.h:694
void set_n_roots(size_t roots) override
Definition IterativeSolverTemplate.h:290
std::shared_ptr< ArrayHandlers< R, Q, P > > m_handlers
Array handlers.
Definition IterativeSolverTemplate.h:693
fapply_on_p_type m_apply_p
function that evaluates effect of action on the P space projection
Definition IterativeSolverTemplate.h:706
void solution(const std::vector< int > &roots, std::vector< R > ¶meters, std::vector< R > &residual) override
Definition IterativeSolverTemplate.h:260
void set_max_iter(int n) override
Definition IterativeSolverTemplate.h:381
void check_consistent_number_of_roots_and_solutions(const std::vector< TTT > &roots, const size_t nparams)
Definition IterativeSolverTemplate.h:680
void set_max_p(int n) override
Definition IterativeSolverTemplate.h:383
std::shared_ptr< subspace::ISubspaceSolver< R, Q, P > > m_subspace_solver
solves the subspace problem
Definition IterativeSolverTemplate.h:695
void set_p_threshold(value_type_abs threshold) override
Definition IterativeSolverTemplate.h:385
std::vector< size_t > suggest_p(const CVecRef< R > &solution, const CVecRef< R > &residual, size_t max_number, value_type_abs threshold) override
Definition IterativeSolverTemplate.h:281
int get_max_p() const override
Definition IterativeSolverTemplate.h:384
size_t n_roots() const override
Definition IterativeSolverTemplate.h:288
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
size_t m_max_p
maximum size of P space
Definition IterativeSolverTemplate.h:709
const subspace::Dimensions & dimensions() const override
Access dimensions of the subspace.
Definition IterativeSolverTemplate.h:388
size_t solve_and_generate_working_set(const VecRef< R > ¶meters, const VecRef< R > &action)
Solves the subspace problems and selects the working set of roots, returning their parameters and res...
Definition IterativeSolverTemplate.h:632
const std::shared_ptr< molpro::profiler::Profiler > & profiler() const override
Definition IterativeSolverTemplate.h:397
IterativeSolverTemplate(std::shared_ptr< subspace::IXSpace< R, Q, P > > xspace, std::shared_ptr< subspace::ISubspaceSolver< R, Q, P > > solver, std::shared_ptr< ArrayHandlers< R, Q, P > > handlers, std::shared_ptr< Statistics > stats, std::shared_ptr< Logger > logger)
Definition IterativeSolverTemplate.h:583
virtual ~IterativeSolverTemplate()
Definition IterativeSolverTemplate.h:596
int add_vector(std::vector< R > ¶meters, std::vector< R > &actions) override
Definition IterativeSolverTemplate.h:211
bool test_problem(const Problem< R > &problem, R &v0, R &v1, int verbosity, value_type_abs threshold) const override
Definition IterativeSolverTemplate.h:527
void solution_params(R ¶meters) override
Definition IterativeSolverTemplate.h:278
virtual bool linearEigensystem() const
Definition IterativeSolverTemplate.h:623
const Statistics & statistics() const override
Definition IterativeSolverTemplate.h:324
const std::vector< value_type_abs > & errors() const override
Definition IterativeSolverTemplate.h:322
void solution(R ¶meters, R &residual) override
Definition IterativeSolverTemplate.h:263
size_t m_nroots
number of roots the solver is searching for
Definition IterativeSolverTemplate.h:699
bool m_end_iteration_needed
whether end_iteration should be called after any preconditioner
Definition IterativeSolverTemplate.h:715
void solution_params(const std::vector< int > &roots, const VecRef< R > ¶meters) override
Definition IterativeSolverTemplate.h:271
int add_vector(const VecRef< R > ¶meters, const VecRef< R > &actions) override
Definition IterativeSolverTemplate.h:186
void clearP() override
Definition IterativeSolverTemplate.h:232
bool solve(R ¶meters, R &actions, const Problem< R > &problem, bool generate_initial_guess=false) override
Definition IterativeSolverTemplate.h:517
bool end_iteration_needed() override
Definition IterativeSolverTemplate.h:688
IterativeSolverTemplate(const IterativeSolverTemplate< Solver, R, Q, P > &)=delete
void report() const override
Definition IterativeSolverTemplate.h:352
bool m_normalise_solution
whether to normalise the solutions
Definition IterativeSolverTemplate.h:705
const std::vector< int > & working_set() const override
Definition IterativeSolverTemplate.h:286
std::shared_ptr< Logger > m_logger
logger
Definition IterativeSolverTemplate.h:704
void set_convergence_threshold_value(value_type_abs thresh) override
Definition IterativeSolverTemplate.h:359
virtual void set_value_errors()
Implementation class should overload this to set errors in the current values (e.g....
Definition IterativeSolverTemplate.h:619
bool solve(std::vector< R > ¶meters, std::vector< R > &actions, const Problem< R > &problem, bool generate_initial_guess=false) override
Definition IterativeSolverTemplate.h:522
void set_logger(std::shared_ptr< Logger > logger) override
Definition IterativeSolverTemplate.h:177
virtual void construct_residual(const std::vector< int > &roots, const CVecRef< R > ¶ms, const VecRef< R > &actions)=0
Constructs residual for given roots provided their parameters and actions.
void set_options(const Options &options) override
Definition IterativeSolverTemplate.h:296
int add_vector(R ¶meters, R &actions, value_type value=0) override
Definition IterativeSolverTemplate.h:214
value_type_abs m_convergence_threshold_value
value changes less than this mark a converged solution
Definition IterativeSolverTemplate.h:701
IterativeSolverTemplate()=delete
void finalize() override
Definition IterativeSolverTemplate.h:690
void set_verbosity(Verbosity v) override
Definition IterativeSolverTemplate.h:361
bool solve(const VecRef< R > ¶meters, const VecRef< R > &actions, const Problem< R > &problem, bool generate_initial_guess=false) override
Definition IterativeSolverTemplate.h:399
int m_max_iter
maximum number of iterations in solve()
Definition IterativeSolverTemplate.h:708
std::shared_ptr< Statistics > m_stats
accumulates statistics of operations performed by the solver
Definition IterativeSolverTemplate.h:703
value_type_abs get_p_threshold() const override
Definition IterativeSolverTemplate.h:386
Logger & logger() override
Definition IterativeSolverTemplate.h:184
value_type_abs m_convergence_threshold
residual norms less than this mark a converged solution
Definition IterativeSolverTemplate.h:700
void set_verbosity(int v) override
Definition IterativeSolverTemplate.h:362
Verbosity get_verbosity() const override
Definition IterativeSolverTemplate.h:380
void solution(const std::vector< int > &roots, const VecRef< R > ¶meters, const VecRef< R > &residual) override
Definition IterativeSolverTemplate.h:234
IterativeSolverTemplate(IterativeSolverTemplate< Solver, R, Q, P > &&) noexcept=default
void warn(std::string_view message, Ts &&...args) const
Definition Logger.h:510
Abstract class defining the problem-specific interface for the simplified solver interface to Iterati...
Definition IterativeSolver.h:85
virtual void action(const CVecRef< R > ¶meters, 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
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
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 ¶meters, 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 ¶meters) const
Provide values of R vectors for testing the problem class. For use in a non-linear solver,...
Definition IterativeSolver.h:189
Full subspace.
Definition IXSpace.h:19
Matrix container that allows simple data access, slicing, copying and resizing without loosing data.
Definition Matrix.h:32
static std::shared_ptr< Profiler > single()
void construct_solution(const VecRef< R > ¶ms, const std::vector< int > &roots, const subspace::Matrix< value_type > &solutions, const std::vector< std::reference_wrapper< P > > &pparams, const std::vector< std::reference_wrapper< Q > > &qparams, const std::vector< std::reference_wrapper< Q > > &dparams, size_t oP, size_t oQ, size_t oD, ArrayHandlers< R, Q, P > &handlers)
Definition IterativeSolverTemplate.h:38
std::vector< std::vector< T > > construct_vectorP(const std::vector< int > &roots, const subspace::Matrix< T > &solutions, const size_t oP, const size_t nP)
Definition IterativeSolverTemplate.h:72
void normalise(const size_t n_roots, const VecRef< R > ¶ms, const VecRef< R > &actions, array::ArrayHandler< R, R > &handler, Logger &logger)
Definition IterativeSolverTemplate.h:84
std::vector< std::pair< size_t, size_t > > parameter_batches(const size_t nsol, const size_t nparam)
Definition IterativeSolverTemplate.h:25
std::vector< int > select_working_set(const size_t nw, const std::vector< T > &errors, const T threshold, const std::vector< T > &value_errors, const T value_threshold)
Definition IterativeSolverTemplate.h:111
void update_errors(std::vector< T > &errors, const CVecRef< R > &residual, array::ArrayHandler< R, R > &handler)
Definition IterativeSolverTemplate.h:102
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition helper.h:14
auto cwrap(ForwardIt begin, ForwardIt end)
Takes a begin and end iterators and returns a vector of references to each element.
Definition wrap.h:52
auto wrap_arg(T &&arg, S &&... args) -> std::enable_if_t< std::conjunction_v< std::is_same< decay_t< T >, decay_t< S > >... >, VecRef< decay_t< T > > >
Constructs a vector of reference wrappers with provided arguments.
Definition wrap.h:135
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
Verbosity
Specifies how much detail IterativeSolver::solve should write to output.
Definition Options.h:12
@ Summary
only summary at the start and end of solve
@ Detailed
Iteration plus more detail such as operation count.
@ Iteration
Summary plus minimal results at each iteration.
void read_handler_counts(std::shared_ptr< Statistics > stats, std::shared_ptr< ArrayHandlers< R, Q, P > > handlers)
Definition Statistics.h:30
real_type_t< T > real_part(const T &x)
The real part of a scalar; the value itself for a real type.
Definition scalar_traits.h:58
const std::shared_ptr< const molpro::Options > options()
Get the Options object associated with iterative-solver.
Definition linalg_options.cpp:4
Access point for different options in iterative solvers.
Definition Options.h:20
Information about performance of IterativeSolver instance.
Definition Statistics.h:10
Definition IterativeSolverTemplate.h:142
static constexpr const char * name
Definition IterativeSolverTemplate.h:143
Definition IterativeSolverTemplate.h:132
static constexpr std::size_t iter
Definition IterativeSolverTemplate.h:134
static constexpr std::size_t errors
Definition IterativeSolverTemplate.h:135
static constexpr const char * name
Definition IterativeSolverTemplate.h:133
Definition IterativeSolverTemplate.h:150
static constexpr const char * name
Definition IterativeSolverTemplate.h:151
Definition Dimensions.h:9
Manages solution of the subspace problem and storage of those solutions.
Definition ISubspaceSolver.h:21