iterative-solver 0.0
DSpaceResetter.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_DSPACERESETTER_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_DSPACERESETTER_H
3#include <molpro/linalg/itsolv/IterativeSolver.h>
4#include <molpro/linalg/itsolv/propose_rspace.h>
5#include <molpro/linalg/itsolv/subspace/Dimensions.h>
6#include <molpro/linalg/itsolv/subspace/IXSpace.h>
7#include <molpro/linalg/itsolv/subspace/QSpace.h>
8#include <molpro/linalg/itsolv/subspace/gram_schmidt.h>
9#include <molpro/linalg/itsolv/subspace/util.h>
10#include <molpro/linalg/itsolv/util.h>
11
14template <class R, class Q, class P, typename value_type>
16 int m_max_Qsize_after_reset, Logger& logger) {
17 logger.msg("resize_qspace()", Logger::Trace);
18 auto q_delete = limit_qspace_size(xspace.dimensions(), m_max_Qsize_after_reset, solutions, logger);
19 logger.msg("delete Q parameter indices = ", q_delete.begin(), q_delete.end(), Logger::Debug);
20 std::sort(begin(q_delete), end(q_delete), std::greater<int>());
21 for (auto iq : q_delete)
22 xspace.eraseq(iq);
23}
24
32template <class R, class Q>
33auto max_overlap_with_R(const CVecRef<R>& rparams, const CVecRef<Q>& qparams, array::ArrayHandler<R, Q>& handler,
34 Logger& logger) {
35 logger.msg("max_overlap_with_R()", Logger::Trace);
36 const auto nR = rparams.size();
37 auto overlap = subspace::util::overlap(rparams, qparams, handler);
38 auto q_indices = std::vector<int>(qparams.size());
39 std::iota(std::begin(q_indices), std::end(q_indices), 0);
40 auto q_max_overlap = std::vector<int>{};
41 for (size_t i = 0; i < nR && !q_indices.empty(); ++i) {
42 auto ov = std::vector<typename array::ArrayHandler<R, Q>::value_type_abs>{};
43 for (auto j : q_indices)
44 ov.push_back(std::abs(overlap(i, j)));
45 auto it_max = std::max_element(ov.begin(), ov.end());
46 auto i_max = std::distance(ov.begin(), it_max);
47 logger.msg("removed q index = " + std::to_string(q_indices[i_max]) + ", with overlap = " + std::to_string(*it_max),
49 q_max_overlap.push_back(q_indices[i_max]);
50 q_indices.erase(q_indices.begin() + i_max);
51 }
52 std::sort(std::begin(q_max_overlap), std::end(q_max_overlap), std::greater<int>());
53 return q_max_overlap;
54}
55
69template <class Q>
71protected:
72 int m_nreset = std::numeric_limits<int>::max();
73 int m_max_Qsize_after_reset = std::numeric_limits<int>::max();
74 std::list<Q> solution_params;
75
76public:
77 DSpaceResetter() = default;
78 DSpaceResetter(int nreset, int max_Qsize) : m_nreset{nreset}, m_max_Qsize_after_reset{max_Qsize} {}
79
81 bool do_reset(size_t iter, const subspace::Dimensions& dims) {
82 return ((iter + 1) % m_nreset == 0 && dims.nD > 0) || !solution_params.empty();
83 }
84
85 void set_nreset(size_t i) {
86 assert(i >= 0);
87 m_nreset = i;
88 }
89 auto get_nreset() const { return m_nreset; }
90 void set_max_Qsize(size_t i) {
91 assert(i >= 0);
93 }
94 auto get_max_Qsize() const { return m_max_Qsize_after_reset; }
95
97 template <class R, class P, typename value_type, typename value_type_abs>
98 std::vector<int> run(const VecRef<R>& rparams, subspace::IXSpace<R, Q, P>& xspace,
99 const subspace::Matrix<value_type>& solutions, const value_type_abs norm_thresh,
100 const value_type_abs svd_thresh, ArrayHandlers<R, Q, P>& handlers, Logger& logger) {
101 logger.msg("DSpaceResetter::run()", Logger::Trace);
102 logger.msg("dimensions {nP, nQ, nD, nR} = " + std::to_string(xspace.dimensions().nP) + ", " +
103 std::to_string(xspace.dimensions().nQ) + ", " + std::to_string(xspace.dimensions().nD) + ", " +
104 std::to_string(rparams.size()),
106 auto solutions_proj = solutions;
107 if (solution_params.empty() && !rparams.empty()) {
108 logger.msg("constructing solutions", Logger::Debug);
109 const auto dims = xspace.dimensions();
110 const auto overlap = xspace.data.at(subspace::EqnData::S);
111 auto q_indices = std::vector<int>(xspace.dimensions().nQ);
112 std::iota(q_indices.begin(), q_indices.end(), 0);
113 solutions_proj = dspace::construct_projected_solution(solutions, dims, q_indices, logger);
114 auto overlap_proj =
115 dspace::construct_projected_solutions_overlap(solutions_proj, overlap, dims, q_indices, logger);
116 dspace::remove_null_norm_and_normalise(solutions_proj, overlap_proj, norm_thresh, logger);
117 solutions_proj = dspace::remove_null_projected_solutions(solutions_proj, overlap_proj, svd_thresh, logger);
118 overlap_proj = dspace::construct_projected_solutions_overlap(solutions_proj, overlap, dims, q_indices, logger);
119 dspace::remove_null_norm_and_normalise(solutions_proj, overlap_proj, norm_thresh, logger);
120 const auto nC = solutions_proj.rows();
121 for (size_t i = 0; i < nC; ++i)
122 solution_params.emplace_back(util::construct_zeroed_copy(rparams.front().get(), handlers.qr()));
123 auto roots = std::vector<int>(nC);
124 std::iota(begin(roots), end(roots), 0);
125 util::construct_solutions(wrap(begin(solution_params), end(solution_params)), roots, solutions_proj, {},
126 xspace.cparamsq(), xspace.cparamsd(), 0, 0, dims.nQ, handlers.qq(), handlers.qp(),
127 handlers.qq());
128 VecRef<Q> null_params, null_actions;
129 xspace.update_dspace(null_params, null_actions);
130 }
131 const auto nR = std::min(rparams.size(), solution_params.size());
132 for (size_t i = 0; i < nR; ++i) {
133 handlers.rq().copy(rparams[i], solution_params.front());
134 solution_params.pop_front();
135 }
136 const auto wparams = cwrap(begin(rparams), begin(rparams) + nR);
137 auto q_delete = max_overlap_with_R(wparams, xspace.cparamsq(), handlers.rq(), logger);
138 for (auto i : q_delete)
139 xspace.eraseq(i);
140 if (xspace.dimensions().nQ + nR > size_t(m_max_Qsize_after_reset))
141 resize_qspace(xspace, solutions, size_t(m_max_Qsize_after_reset) > nR ? m_max_Qsize_after_reset - nR : 0, logger);
142 auto new_working_set = std::vector<int>(nR);
143 std::iota(begin(new_working_set), end(new_working_set), 0);
144 return new_working_set;
145 }
146};
147
148} // namespace molpro::linalg::itsolv::detail
149#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_DSPACERESETTER_H
Enhances various operations between pairs of arrays and allows dynamic code injection with uniform in...
Definition: ArrayHandler.h:162
Class, containing a collection of array handlers used in IterativeSolver Provides a Builder sub-class...
Definition: ArrayHandlers.h:25
auto & qr()
Definition: ArrayHandlers.h:43
auto & qq()
Definition: ArrayHandlers.h:40
auto & qp()
Definition: ArrayHandlers.h:45
auto & rq()
Definition: ArrayHandlers.h:42
Resets D space constructing full solutions as the new working set, removing instabilities from Q spac...
Definition: DSpaceResetter.h:70
auto get_nreset() const
Definition: DSpaceResetter.h:89
int m_max_Qsize_after_reset
maximum size of Q space after reset
Definition: DSpaceResetter.h:73
bool do_reset(size_t iter, const subspace::Dimensions &dims)
Whether reset operation should be run.
Definition: DSpaceResetter.h:81
std::list< Q > solution_params
all current solutions that will be moved to the Q space
Definition: DSpaceResetter.h:74
void set_max_Qsize(size_t i)
Definition: DSpaceResetter.h:90
std::vector< int > run(const VecRef< R > &rparams, subspace::IXSpace< R, Q, P > &xspace, const subspace::Matrix< value_type > &solutions, const value_type_abs norm_thresh, const value_type_abs svd_thresh, ArrayHandlers< R, Q, P > &handlers, Logger &logger)
Run the reset operation.
Definition: DSpaceResetter.h:98
void set_nreset(size_t i)
Definition: DSpaceResetter.h:85
auto get_max_Qsize() const
Definition: DSpaceResetter.h:94
int m_nreset
reset D space every n iterations
Definition: DSpaceResetter.h:72
DSpaceResetter(int nreset, int max_Qsize)
Definition: DSpaceResetter.h:78
virtual CVecRef< Q > cparamsq() const =0
SubspaceData data
Equation data in the subspace.
Definition: IXSpace.h:22
virtual void eraseq(size_t i)=0
Removes parameter i from Q subspace.
virtual CVecRef< Q > cparamsd() const =0
virtual const Dimensions & dimensions() const =0
virtual void update_dspace(VecRef< Q > &params, VecRef< Q > &actions)=0
Updates D space with the new parameters.
auto construct_projected_solutions_overlap(const subspace::Matrix< value_type > &solutions_proj, const subspace::Matrix< value_type > &overlap, const subspace::Dimensions &dims, const std::vector< int > &remove_qspace, Logger &logger)
Constructs overlap matrix for projected solutions.
Definition: propose_rspace.h:74
auto remove_null_projected_solutions(const subspace::Matrix< value_type > &solutions_proj, const subspace::Matrix< value_type > &overlap_proj, const value_type_abs svd_thresh, Logger &logger)
Transforms to a stable subspace of projected solutions via SVD.
Definition: propose_rspace.h:159
void remove_null_norm_and_normalise(subspace::Matrix< value_type > &parameters, subspace::Matrix< value_type > &overlap, const value_type_abs norm_thresh, Logger &logger)
Removes parameters with norm less than threshold and normalises the rest.
Definition: propose_rspace.h:118
auto construct_projected_solution(const subspace::Matrix< value_type > &solutions, const subspace::Dimensions &dims, const std::vector< int > &remove_qspace, Logger &logger)
Projects solution from the full subspace on to Q_{delete} and current D space.
Definition: propose_rspace.h:40
Definition: IterativeSolverTemplate.h:19
auto limit_qspace_size(const subspace::Dimensions &dims, const size_t max_size_qspace, const subspace::Matrix< value_type > &solutions, Logger &logger)
Ensures that size Q space is within limit by proposing Q parameters for deletion.
Definition: propose_rspace.h:311
void resize_qspace(subspace::IXSpace< R, Q, P > &xspace, const subspace::Matrix< value_type > &solutions, int m_max_Qsize_after_reset, Logger &logger)
Removes Q parameters that have smallest contribution to any solution until Q space size is within lim...
Definition: DSpaceResetter.h:15
auto max_overlap_with_R(const CVecRef< R > &rparams, const CVecRef< Q > &qparams, array::ArrayHandler< R, Q > &handler, Logger &logger)
Returns list of Q indices with maximum overlap to R parameters, sorted in descending order.
Definition: DSpaceResetter.h:33
auto overlap(const CVecRef< R > &left, const CVecRef< Q > &right, array::ArrayHandler< Z, W > &handler) -> std::enable_if_t< detail::Z_and_W_are_one_of_R_and_Q< R, Q, Z, W >, Matrix< double > >
Calculates overlap matrix between left and right vectors.
Definition: util.h:49
void construct_solutions(const VecRef< R > &params, const std::vector< int > &roots, const subspace::Matrix< double > &solutions, const CVecRef< P > &pparams, const CVecRef< Q > &qparams, const CVecRef< Q > &dparams, size_t oP, size_t oQ, size_t oD, array::ArrayHandler< R, R > &handler_rr, array::ArrayHandler< R, P > &handler_rp, array::ArrayHandler< R, Q > &handler_rq)
Construct solutions.
Definition: util.h:70
Q construct_zeroed_copy(const R &param, array::ArrayHandler< Q, R > &handler)
Copy R parameter to Q and zero it. This ensures same size and distribution of the copy.
Definition: util.h:48
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(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
A dummy structured logger.
Definition: Logger.h:40
void msg(const std::string &message, Level log_lvl)
Definition: Logger.cpp:16
@ Trace
Definition: Logger.h:49
@ Debug
Definition: Logger.h:49
Stores partitioning of XSpace into P, Q and R blocks with sizes and offsets for each one.
Definition: Dimensions.h:5
size_t nD
Definition: Dimensions.h:10
size_t nQ
Definition: Dimensions.h:9
size_t nP
Definition: Dimensions.h:8