iterative-solver 0.0
 
Loading...
Searching...
No Matches
QSpace.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_QSPACE_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_QSPACE_H
3#include <array>
4#include <algorithm>
5#include <cassert>
6#include <functional>
7#include <list>
8
9#include <molpro/linalg/itsolv/ArrayHandlers.h>
10#include <molpro/linalg/itsolv/Logger.h>
11#include <molpro/linalg/itsolv/subspace/Dimensions.h>
12#include <molpro/linalg/itsolv/subspace/PSpace.h>
13#include <molpro/linalg/itsolv/subspace/SubspaceData.h>
14#include <molpro/linalg/itsolv/wrap.h>
15#include <molpro/linalg/itsolv/util.h>
16#include <molpro/linalg/itsolv/helper-implementation.h>
17
19
20namespace qspace {
24template <class Q>
25struct QParam {
26 std::unique_ptr<Q> param;
27 std::unique_ptr<Q> action;
28 size_t id;
29 std::unique_ptr<Q> metric_action;
30};
31
33template <class Q, class ForwardIt>
35 auto param_action = std::array<CVecRef<Q>, 2>{};
36 for (auto it = begin; it != end; ++it) {
37 param_action[0].emplace_back(*it->param);
38 param_action[1].emplace_back(*it->action);
39 }
40 return param_action;
41}
42
43template <class Q, class ForwardIt>
45 auto param_action = std::array<VecRef<Q>, 2>{};
46 for (auto it = begin; it != end; ++it) {
47 param_action[0].emplace_back(*it->param);
48 param_action[1].emplace_back(*it->action);
49 }
50 return param_action;
51}
52} // namespace qspace
53
61template <class Rt, class Qt, class Pt>
62struct QSpace {
63 using R = Rt;
64 using Q = Qt;
65 using P = Pt;
68
69 explicit QSpace(std::shared_ptr<ArrayHandlers<R, Q, P>> handlers, std::shared_ptr<Logger> logger)
70 : m_handlers(std::move(handlers)), m_logger(std::move(logger)) {}
71
73 void set_logger(std::shared_ptr<Logger> logger) { m_logger = std::move(logger); }
74
89 template <typename T>
93 m_logger->trace("QSpace::update");
94 assert(metric_actions.empty() || metric_actions.size() == params.size());
95 auto it_begin = m_params.begin();
96 for (size_t i = 0; i < params.size(); ++i) {
97 m_params.emplace(
99 qspace::QParam<Q>{std::make_unique<Q>(m_handlers->qr().copy(params.at(i))),
100 std::make_unique<Q>(m_handlers->qr().copy(actions.at(i))), m_unique_id++,
101 metric_actions.empty() ? nullptr
102 : std::make_unique<Q>(m_handlers->qr().copy(metric_actions.at(i)))});
103 }
104 size_t nQnew = params.size();
105 auto qq = qq_in;
106 auto qx = qx_in;
107 auto xq = xq_in;
108 if (nQnew > 1) {
111 // New parameters occupy the first nQnew positions of m_params, in the same order as the rows/cols of qq.
112 // Remove the redundant ones from the highest index down so that the remaining indices stay valid.
113 std::sort(rp.begin(), rp.end(), std::greater<>());
114 for (auto i : rp) {
115 m_params.erase(std::next(m_params.begin(), i));
116 for (auto d : square_blocks(qq)) {
117 qq.at(d).remove_row_col(i, i);
118 qx.at(d).remove_row(i);
119 xq.at(d).remove_col(i);
120 }
121 if (!qq.at(EqnData::rhs).empty())
122 qq.at(EqnData::rhs).remove_row(i);
123 }
124 nQnew -= rp.size();
125 }
126 const auto nXnew = dims.nX() + nQnew;
127 auto data = old_data;
128 for (auto d : square_blocks(qq)) {
129 data[d].resize({dims.nX() + nQnew, dims.nX() + nQnew});
130 data[d].slice({dims.oQ() + nQnew, dims.oQ() + nQnew}, {data[d].rows(), data[d].cols()}) =
131 old_data[d].slice({dims.oQ(), dims.oQ()}, {dims.nX(), dims.nX()});
132 data[d].slice({dims.oQ(), dims.oQ()}, {dims.oQ() + nQnew, dims.oQ() + nQnew}) =
133 qq.at(d).slice({0, 0}, {nQnew, nQnew});
134 data[d].slice({dims.oQ(), 0}, {dims.oQ() + nQnew, dims.oQ()}) = qx.at(d).slice({0, 0}, {nQnew, dims.oQ()});
135 data[d].slice({dims.oQ(), dims.oQ() + nQnew}, {dims.oQ() + nQnew, nXnew}) =
136 qx.at(d).slice({0, dims.oQ()}, {nQnew, dims.nX()});
137 data[d].slice({0, dims.oQ()}, {dims.oQ(), dims.oQ() + nQnew}) = xq.at(d).slice({0, 0}, {dims.oQ(), nQnew});
138 data[d].slice({dims.oQ() + nQnew, dims.oQ()}, {nXnew, dims.oQ() + nQnew}) =
139 xq.at(d).slice({dims.oQ(), 0}, {dims.nX(), nQnew});
140 data[d].slice({0, 0}, {dims.oQ(), dims.oQ()}) = old_data[d].slice({0, 0}, {dims.oQ(), dims.oQ()});
141 data[d].slice({0, dims.oQ() + nQnew}, {dims.oQ(), nXnew}) =
142 old_data[d].slice({0, dims.oQ()}, {dims.oQ(), dims.nX()});
143 data[d].slice({dims.oQ() + nQnew, 0}, {nXnew, dims.oQ()}) =
144 old_data[d].slice({dims.oQ(), 0}, {dims.nX(), dims.oQ()});
145 old_data[d] = data[d];
146 }
147 if (!qq.at(EqnData::rhs).empty()) {
148 data[EqnData::rhs].resize({dims.nX() + nQnew, dims.nRHS});
149 data[EqnData::rhs].slice({dims.oQ(), 0}, {dims.oQ() + nQnew, dims.nRHS}) = qq.at(EqnData::rhs).slice();
150 data[EqnData::rhs].slice({dims.oQ() + nQnew, 0}, {dims.nX() + nQnew, dims.nRHS}) =
151 old_data[EqnData::rhs].slice({dims.oQ(), 0}, {dims.nX(), dims.nRHS});
153 }
154 m_logger->data_dump("S = ", data.at(EqnData::S));
155 m_logger->data_dump("H = ", data.at(EqnData::H));
156 if (data.count(EqnData::M))
157 m_logger->data_dump("M = ", data.at(EqnData::M));
158 m_logger->data_dump("rhs = ", data.at(EqnData::rhs));
159 }
160
161 void clear() { m_params.clear(); }
162
164 void erase(size_t i) {
165 assert(m_params.size() > i);
166 auto it = std::next(begin(m_params), i);
167 m_params.erase(it);
168 }
169
170 size_t size() const { return m_params.size(); }
171
173 auto qparams = qspace::wrap_params<Q>(m_params.begin(), m_params.end());
174 return qparams[0];
175 }
176
178 auto qparams = qspace::cwrap_params<Q>(m_params.begin(), m_params.end());
179 return qparams[0];
180 }
181
182 CVecRef<Q> cparams() const { return params(); }
183
185 auto qparams = qspace::wrap_params<Q>(m_params.begin(), m_params.end());
186 return qparams[1];
187 }
188
190 auto qparams = qspace::cwrap_params<Q>(m_params.begin(), m_params.end());
191 return qparams[1];
192 }
193
194 CVecRef<Q> cactions() const { return actions(); }
195
198 auto metric_actions = CVecRef<Q>{};
199 for (const auto& p : m_params)
200 if (p.metric_action)
201 metric_actions.emplace_back(*p.metric_action);
202 return metric_actions;
203 }
204
205protected:
206 std::shared_ptr<ArrayHandlers<R, Q, P>> m_handlers;
207 std::shared_ptr<Logger> m_logger;
208 size_t m_unique_id{0};
209 std::list<qspace::QParam<Q>> m_params;
210};
211
212} // namespace molpro::linalg::itsolv::subspace
213
214#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_QSPACE_H
decltype(value_type_L{} *value_type_R{}) value_type
Definition ArrayHandler.h:182
decltype(check_abs< value_type >()) value_type_abs
Definition ArrayHandler.h:183
Class, containing a collection of array handlers used in IterativeSolver Provides a Builder sub-class...
Definition ArrayHandlers.h:25
auto redundant_parameters(const subspace::Matrix< value_type > &overlap, const size_t oR, const size_t nR, const value_type_abs svd_thresh, Logger &logger)
Deduces a set of parameters that are redundant due to linear dependencies.
Definition helper-implementation.h:960
auto wrap_params(ForwardIt begin, ForwardIt end)
Definition QSpace.h:44
auto cwrap_params(ForwardIt begin, ForwardIt end)
Generates vector of reference wrappers to param and action in a range of QParam objects.
Definition QSpace.h:34
std::map< EqnData, Matrix< T > > SubspaceData
Equation data blocks of the subspace, in the scalar type of the problem.
Definition SubspaceData.h:18
std::vector< EqnData > square_blocks(const SubspaceData< T > &data)
The square matrices, H, S and, if present, M, among the equation data.
Definition SubspaceData.h:22
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
std::vector< std::reference_wrapper< const A > > CVecRef
Definition wrap.h:14
std::vector< std::reference_wrapper< A > > VecRef
Definition wrap.h:11
Container storing the Q space parameters.
Definition QSpace.h:62
typename array::ArrayHandler< R, R >::value_type_abs value_type_abs
Definition QSpace.h:67
void update(const CVecRef< R > &params, const CVecRef< R > &actions, const SubspaceData< T > &qq_in, const SubspaceData< T > &qx_in, const SubspaceData< T > &xq_in, const Dimensions &dims, SubspaceData< T > &old_data, const CVecRef< R > &metric_actions={})
Prepends parameters to the start of Q space.
Definition QSpace.h:90
std::shared_ptr< ArrayHandlers< R, Q, P > > m_handlers
Definition QSpace.h:206
VecRef< Q > params()
Definition QSpace.h:172
typename array::ArrayHandler< R, R >::value_type value_type
Definition QSpace.h:66
CVecRef< Q > cactions() const
Definition QSpace.h:194
size_t size() const
Definition QSpace.h:170
void clear()
Definition QSpace.h:161
CVecRef< Q > cparams() const
Definition QSpace.h:182
CVecRef< Q > cmetric_actions() const
Actions of the metric, empty unless there is a metric.
Definition QSpace.h:197
size_t m_unique_id
unique id for any new parameter set
Definition QSpace.h:208
void erase(size_t i)
Erases q parameter i.
Definition QSpace.h:164
std::list< qspace::QParam< Q > > m_params
q parameter sets with new parameters first
Definition QSpace.h:209
std::shared_ptr< Logger > m_logger
Definition QSpace.h:207
VecRef< Q > actions()
Definition QSpace.h:184
QSpace(std::shared_ptr< ArrayHandlers< R, Q, P > > handlers, std::shared_ptr< Logger > logger)
Definition QSpace.h:69
CVecRef< Q > params() const
Definition QSpace.h:177
CVecRef< Q > actions() const
Definition QSpace.h:189
void set_logger(std::shared_ptr< Logger > logger)
Replaces the logger.
Definition QSpace.h:73
Parameter in the Q space.
Definition QSpace.h:25
std::unique_ptr< Q > param
parameter
Definition QSpace.h:26
std::unique_ptr< Q > action
corresponding action
Definition QSpace.h:27
size_t id
unique id
Definition QSpace.h:28
std::unique_ptr< Q > metric_action
corresponding action of the metric, null unless there is one
Definition QSpace.h:29